--[[
	基本的函数集合
	基本参照原来的base函数，里面有些函数是多余的
	把调用定时器的两个函数加入进来了。 
--]]
local debug = debug
local skynet = require "skynet"
local netpack = require "skynet.websocketnetpack"
local string = string
local tostring = tostring
local math = math 
local table = table
local Base = {}
local randomnum = 0
local mailcount = 0

-- 原来Timer里的两个函数，设置，清除定时器
function Base.settimer(ms10_time, msgname, msg)
	return skynet.call(".timercenter", "lua", "settimer", ms10_time, msgname, msg)  
end

function Base.cleartimer(timerid)
	skynet.send(".timercenter", "lua", "cleartimer", timerid)
end

--xpcall调用
function Base.xpcall(func, ...)
	if Base.isdebug() then
	 	return xpcall(func,  function (err) return debug.traceback(err, 2) end, ...)
	end
	return true, func(...)
end


-- 这个函数没有任何意义。只多写了一句
function Base.skynet_retpack(...)
	pcall(skynet.retpack, ...)
end

function Base.strtrim(str)
	return str:match "^%s*(.-)%s*$"
end

function Base.strsplit(str, delim)
	if type(delim) ~= "string" or string.len(delim) <= 0 then
	return
	end 
	local start = 1
	local t = {}
	while true do
	local pos = string.find (str, delim, start, true) -- plain find
	if not pos then
		break
	end
	table.insert (t, string.sub (str, start, pos - 1))
	start = pos + string.len (delim)
	end
	table.insert (t, string.sub (str, start))
	return t
end

function Base.isdebug()
	if(skynet.getenv("runtime") == "d") then
	return true
	else
	return false
	end
end

--计算字符串的数字hash值
function Base.strtohash(text)
	local counter = 1
	local len = string.len(text)
	for i = 1, len, 3 do 
		counter = math.fmod(counter*8161, 4294967279) +	-- 2^32 - 17: Prime!
		(string.byte(text,i)*16776193) +
		((string.byte(text,i+1) or (len-i+256))*8372226) +
		((string.byte(text,i+2) or (len-i+256))*3932164)
	end
	return math.fmod(counter, 4294967291) -- 2^32 - 5: Prime (and different from the prime in the loop)
end

--获得随机数函数
function Base.get_random(min, max)
	if randomnum == 0 then
		math.randomseed(tostring( math.floor(netpack.getms())):reverse():sub(1, 6))  
	end
	
	randomnum = randomnum + 1
	if randomnum > 1000 then
		randomnum = 0
	end
	return math.random(min, max)
end

--根据用户生成邮件唯一表示id
function Base.generate_mail_key(rid)
	if mailcount > 100 then
	mailcount = 0
	end
	mailcount = mailcount + 1
	return tostring(rid)..tostring(skynet.time()*100)..mailcount  
end

function Base.RNG()
	local status, urand = skynet.pcall(io.open, '/dev/urandom', 'rb')
	if not status then
	    return 0
	end
	local b = 4
	local m = 256
	local n, s = 0, urand:read (b)

	for i = 1, s:len () do
		n = m * n + s:byte (i)
	end
	io.close(urand)
	return n
end

function Base.generate_uuid()
	local template ="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
	local status, urand = skynet.pcall(io.open,"/dev/urandom", "r")
	local d = urand:read(4)
	math.randomseed(os.time() + d:byte(1) + (d:byte(2) * 256) + (d:byte(3) * 65536) + (d:byte(4) * 4294967296))
	local uuid = string.gsub(template, "x", 
					function (c)
					local v = (c == "x") and math.random(0, 0xf) or math.random(8, 0xb)
					return string.format("%x", v)
					end)

	io.close(urand)
	return uuid
end

--判断文件是否
function Base.is_file_exist(path)
	local file = io.open(path, "rb")
	if file then file:close() end
	return file ~= nil
end

--
--获得debug信息（文件名，行号，函数名）
--
function Base.get_debuginfo(level)
    level = level or 2
    local info = debug.getinfo(level)
    if not info or not info.currentline then return "" end
    return (info.short_src or "") .. " function: " .. (info.name or "unname") .. " line: " .. info.currentline .. "---->>>"
end

return Base